package com.gzsxy.esjy.sign.service.impl;


import com.gzsxy.esjy.sign.async.AsyncWsClient;
import com.gzsxy.esjy.sign.cache.SignCacheManager;
import com.gzsxy.esjy.sign.dto.AndroidSignProtocolDto;
import com.gzsxy.esjy.sign.dto.BaseSignProtocolDto;
import com.gzsxy.esjy.sign.enums.SignTypeEnum;
import com.gzsxy.esjy.sign.exception.SignException;
import com.gzsxy.esjy.sign.service.GSWsChannelService;
import com.gzsxy.esjy.sign.socket.AndroidAsyncWsCallBack;
import com.gzsxy.esjy.sign.socket.ScreenAsyncWsCallBack;
import io.netty.bootstrap.Bootstrap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 *
 * @author zhangxiaolong
 * @since 2022/7/15
 */
@Service("gsWsChannelService")
public class GSWsChannelServiceImpl implements GSWsChannelService {

    @Autowired
    private SignCacheManager signCacheManager;

    @Autowired
    private  Bootstrap bootstrap;

    @Autowired
    private AndroidAsyncWsCallBack androidAsyncWsCallBack;

    @Autowired
    private ScreenAsyncWsCallBack screenAsyncWsCallBack;

    @Override
    public AsyncWsClient connect(String ip, Integer port, BaseSignProtocolDto dto) {
        //封装webstocket
        String webSocketUrlStr = getWebSocketUrlStr(ip, port);
        //判断是否已经连接过签字版（只有当前存在签字任务才会连接签字版的webstocket，处理完立马断开）
        boolean containsKey = signCacheManager.getWebsocketCache().containsKey(webSocketUrlStr);
        if (containsKey) {
            //安卓签字版不支持长链接
            if(dto instanceof AndroidSignProtocolDto){
                throw new SignException("签名设备繁忙");
            }
            AsyncWsClient asyncWsClient = signCacheManager.getWebsocketCache().get(webSocketUrlStr);
            asyncWsClient.setRequestId(dto.getRequestId());
            asyncWsClient.setTaskId(dto.getTaskId());
            //检查通道的开启状态
            if (asyncWsClient.getChannelFuture().channel().isOpen() && asyncWsClient.getChannelFuture().channel().isActive()){
                return asyncWsClient;
            }else {
                asyncWsClient.disconnect();
            }
        }

        AsyncWsClient asyncWsClient;
        //判断当前设备类型
        if (SignTypeEnum.ANDROID.getType() == dto.getDevType()) {
            asyncWsClient = new AsyncWsClient(dto.getTaskId(), ip, port, webSocketUrlStr, androidAsyncWsCallBack, bootstrap);
            asyncWsClient.setDevType(SignTypeEnum.ANDROID.getType());
        } else if (SignTypeEnum.SCREEN.getType() == dto.getDevType()) {
            asyncWsClient = new AsyncWsClient(dto.getTaskId(), ip, port, webSocketUrlStr, screenAsyncWsCallBack, bootstrap);
            asyncWsClient.setDevType(SignTypeEnum.SCREEN.getType());
        } else {
            throw new SignException("不支持业务类型");
        }
        asyncWsClient.setRequestId(dto.getRequestId());
        //连接设备
        asyncWsClient.connect();

        //当前
        signCacheManager.getWebsocketCache().put(webSocketUrlStr, asyncWsClient);
        return asyncWsClient;
    }

    @Override
    public void disconnect(String ip, int port) {
        String webSocketUrlStr = getWebSocketUrlStr(ip, port);
        signCacheManager.clearSignByWsUrl(webSocketUrlStr, true);
    }

    /**
     * 封装签名版的webstocket
     * @param ip
     * @param port
     * @return
     */
    public String getWebSocketUrlStr(String ip, int port) {
        return String.format("ws://%s:%d", ip, port);
    }
}
